package com.karrysong.blog_springboot.service.impl;

import com.karrysong.blog_springboot.enums.ErrorCode;
import com.karrysong.blog_springboot.service.EmailService;
import com.karrysong.blog_springboot.vo.Result;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.mail.javamail.MimeMessageHelper;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import javax.mail.MessagingException;
import javax.mail.internet.MimeMessage;
import javax.servlet.http.HttpSession;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.Random;
import java.util.concurrent.TimeUnit;

/**
 * @ClassName: EmailServiceImpl
 * @Author: KarrySong
 * @Date: 2022/8/25 9:49
 * @Description:
 */
@Service
public class EmailServiceImpl implements EmailService {

    @Autowired
    JavaMailSender javaMailSender;
    @Value("${spring.mail.username}")
    private String emailFrom;
    @Resource
    private RedisTemplate<String, Object> redisTemplate;

    @Override
    public Result sendEmailCheckCode(String emailAddress) {

        //检查是否重复发送邮件
        HashMap<String, Object> map = (HashMap<String, Object>) redisTemplate.opsForValue().get(emailAddress);
        if (map != null && !map.isEmpty()) {
            Long sendTime = (Long) map.get("sendTime");
            long nowTime = System.currentTimeMillis();
            if (sendTime != null && nowTime - sendTime < 60 * 15 * 1000) {
                return Result.fail(ErrorCode.EMAIL_SEND_FREQUENTLY);
            }
        }
        int res = sendCheckCode(emailAddress);
        if (res == -1){
            //发送失败
            return Result.fail(ErrorCode.EMAIL_ERROR);
        }else {
            //记录信息，以备验证
            map = new HashMap<>();
            map.put("checkCode", res);
            map.put("sendTime", System.currentTimeMillis());
            //设置数据，有效期两小时
            redisTemplate.opsForValue().set(emailAddress, map, 2, TimeUnit.HOURS);
            return Result.success(null);
        }
    }

    @Override
    public Result checkEmailCheckCode(String emailAddress, String code) {
        HashMap<String, Object> map = (HashMap<String, Object>) redisTemplate.opsForValue().get(emailAddress);
        if (map != null && !map.isEmpty()){
            //已存邮箱不为空，说明该会话存在验证码
            //邮箱符合
            Long sendTime = (Long) map.get("sendTime");
            long nowTime = System.currentTimeMillis();
            if (nowTime - sendTime <= 60 * 120 * 1000){
                //未超时
                String checkCode = map.get("checkCode") + "";
                if (checkCode.equals(code)){
                    //验证码符合
                    //清空信息
                    redisTemplate.delete(emailAddress);
                    //redisTemplate.opsForValue().set(emailAddress, null);
                    return  Result.success(null);
                }else {
                    return Result.fail(ErrorCode.EMAIL_CODE_ERROR);
                }
            }
        }

        return Result.fail(ErrorCode.EMAIL_INFO_ERROR);
    }

    /**
     * 生成6位数字验证码
     * @return
     */
    private static int getCode(){
        Random r = new Random();
        int code = 100000 + r.nextInt(900000);
        return code;
    }

    /**
     * 发送验证码
     * @param sendEmailAddress 发送邮件地址
     * @return
     */
    private int sendCheckCode(String sendEmailAddress)/* throws MessagingException*/ {
        MimeMessage mailMessage=javaMailSender.createMimeMessage();
        //需要借助Helper类
        MimeMessageHelper helper=new MimeMessageHelper(mailMessage);
        int code = getCode();
        String context="<p>本次服务的验证码是:  <span style='color: red;font-size:30px'>"
                + code
                + " </span> <br>请妥善保存，勿要泄露。</p>" +
                "<p><a href='http://www.karrysong.top/MyBlogWeb' " +
                "style='font-size:30px'>更多关于KarrySong</a></p>"
                + "<p>The verification code of this service is:" +
                " <span style='color: red;font-size:30px'>"
                + code + "</span> <br> Please keep it properly and do not disclose it." +
                "</p><p><a href='http://www.karrysong.top/MyBlogWeb' " +
                "style='font-size:30px'>about more KarrySong</a></p>";
        try {
            helper.setFrom(emailFrom);
            helper.setTo(sendEmailAddress);
            helper.setSubject("KarrySong 验证码 Verification Code");
            //发送时间
            helper.setSentDate(new Date());
            helper.setText(context,true);
            //第一个参数要发送的内容，第二个参数是不是Html格式。
            javaMailSender.send(mailMessage);
        }catch (Exception e){
            e.printStackTrace();
            code = -1;
        }
        return code;
    }
}
